/*  
    Copyright 2010 Mike Eheler <mike.eheler@gmail.com>

    This file is part of Four Falling Blocks Puzzle Game.

    Four Falling Blocks Puzzle Game is free software: you can
	redistribute it and/or modify it under the terms of the GNU General
	Public License as published by the Free Software Foundation, either
	version 3 of the License, or (at your option) any later version.

    Four Falling Blocks Puzzle Game is distributed in the hope that it
	will be useful, but WITHOUT ANY WARRANTY; without even the implied
	warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Four Falling Blocks Puzzle Game.
	
	If not, see <http://www.gnu.org/licenses/>.
*/

#include <cstdlib>
#include <GL/gl.h>

#include "engine.h"
#include "game.h"

namespace FBEngine
{
	static int32_t win_width = 0, win_height = 0;
	static int32_t vp_width = 0, vp_height = 0;

	void blockColour( uint8_t type )
	{
		switch( type )
		{
		case 0: glColor3f( 0.0f, 1.0f, 1.0f ); break;
		case 1: glColor3f( 0.0f, 0.0f, 1.0f ); break;
		case 2: glColor3f( 1.0f, 2.0f/3.0f, 0.0f ); break;
		case 3: glColor3f( 1.0f, 1.0f, 0.0f ); break;
		case 4: glColor3f( 0.0f, 1.0f, 0.0f ); break;
		case 5: glColor3f( 2.0f/3.0f, 0.0f, 1.0f ); break;
		case 6: glColor3f( 1.0f, 0.0f, 0.0f ); break;
		default: glColor3f( 1.0f, 1.0f, 1.0f ); break;
		}
	}

	void init()
	{
		glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
	}

	void resize( int32_t w, int32_t h )
	{
		win_width = w;
		win_height = h;

		if( h > w * 2 ) h = w * 2;
		if( w * 2 > h ) w = h / 2;

		vp_width = w;
		vp_height = h;

		glViewport( (win_width - vp_width) / 2, (win_height - vp_height) / 2, vp_width, vp_height );

		glMatrixMode( GL_PROJECTION );
		glLoadIdentity();
		glOrtho( -0.1, 10.1, -0.1, 20.1, -1.0, 1.0 );

		glMatrixMode( GL_MODELVIEW );
		glLoadIdentity();
	}

	void draw()
	{
		glClear( GL_COLOR_BUFFER_BIT );

		Game * game = Game::instance();

		glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
		glBegin( GL_QUADS );
			glVertex2i( 0, 0 );
			glVertex2i( 0, 20 );
			glVertex2i( 10, 20 );
			glVertex2i( 10, 0 );
		glEnd();

		// draw the board
		glPushMatrix();
		glTranslatef( 0.0f, 19.0f, 0.0f );
		for( uint8_t row = 0; row < 20; row++ )
		{
			glPushMatrix();
			for( uint8_t col = 0; col < 10; col++ )
			{
				blockColour( game->board()->at(row,col) );

				if( game->board()->at(row,col) != -1 )
				{
					glBegin( GL_QUADS );
						glVertex2i( 0, 0 );
						glVertex2i( 0, 1 );
						glVertex2i( 1, 1 );
						glVertex2i( 1, 0 );
					glEnd();
				}
				glTranslatef( 1.0f, 0.0f, 0.0f );
			}
			glPopMatrix();
			glTranslatef( 0.0f, -1.0f, 0.0f );
		}
		glPopMatrix();

		// draw current piece
		if( game->currentPiece() )
		{
			blockColour( game->currentPiece()->type() );
			uint8_t const * shape = game->currentPiece()->shape();
			glPushMatrix();
			glTranslatef( static_cast<GLfloat>(game->positionX()), 19.0f - static_cast<GLfloat>(game->positionY()), 0.0f );
			for( uint8_t y = 0; y < 4; y++ )
			{
				glPushMatrix();
				for( uint8_t x = 0; x < 4; x++ )
				{
					if( shape[y * 4 + x] != 0 )
					{
						glBegin( GL_QUADS );
							glVertex2i( 0, 0 );
							glVertex2i( 0, 1 );
							glVertex2i( 1, 1 );
							glVertex2i( 1, 0 );
						glEnd();
					}
					glTranslatef( 1.0f, 0.0f, 0.0f );
				}
				glPopMatrix();
				glTranslatef( 0.0f, -1.0f, 0.0f );
			}
			glPopMatrix();
		}

		// draw grid
		glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
		glBegin( GL_LINES );
		for( uint8_t row = 0; row <= 20; row++ )
		{
			glVertex2i( 0, row );
			glVertex2i( 10, row );
		}
		for( uint8_t col = 0; col <= 10; col++ )
		{
			glVertex2i( col, 0 );
			glVertex2i( col, 20 );
		}
		glEnd();
	}
};